<template>
  <div>这是首页</div>
  <button @click="minus">-</button>
  <span>{{ count }}</span>
  <button @click="add(2)">+</button>

  <div>doubleCount: {{ doubleCount }}</div>

  <hr />

  <div>
    <input type="text" v-model="state.firstName" />
    <input type="text" v-model="state.lastName" />
  </div>

  <hr />

  <input type="text" ref="ipt" />

  <hr />

  <Child :count="count" @abc="fn" />
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, onMounted, provide } from "vue";
import Child from "./Child.vue";

interface StateType {
  firstName: string;
  lastName: string;
}

// 生命周期里面也不需要做任何的ts的处理
onMounted(() => {
  const a: number = 123;
  console.log(a);
});

// 用ref来定义变量的话，类型要写在ref后面，用泛型的写法
const count = ref<number>(10);
// 事件处理函数的只需要加返回值的类型，加在小括号的后面
const add = (n: number): void => {
  count.value += n;
};
const minus = (): void => {
  count.value--;
};
// watch不需要做任何的ts的处理
watch(count, (val) => {
  console.log(val);
});

// 计算属性的类型和ref一样，也是用泛型
const doubleCount = computed<number>(() => {
  return count.value * 2;
});

const list = ref<number[]>([1, 2, 3, 4, 5, 6, 7]);
const oddList = computed<number[]>(() => {
  return list.value.filter((item) => item % 2);
});

// 使用reactive定义变量的时候，需要使用interface或者as关键字
const state = reactive<StateType>({
  firstName: "zhang",
  lastName: "san",
});
// const state = reactive({
//   firstName: "zhang" as string,
//   lastName: "san" as string,
// });

// HTMLInputElement表示input元素
const ipt = ref<null | HTMLInputElement>(null);
onMounted(() => {
  ipt.value && ipt.value.focus();
  // as表示断言，自己去确定
  // (ipt.value as HTMLInputElement).focus();
});

const fn = (n: number): void => {
  console.log("fn", n);
};

// 依赖不需要加任何的类型
provide("name", "zhaoliu");
</script>
